export const createStore = function(reducer,fn){
  let state;
  let listeners = [];// 事件池 用来存储react-redux传进来的回调函数
  let getState = function(){
    return JSON.parse(JSON.stringify(state))
  }
  let dispatch = function(action){
    //action {type:'add',num:10}
    state = reducer(state,action)
    listeners.forEach(item=>{
      // console.log(item)
      item&&item()
    })
    // reducer的执行结果就是新的state
  }
  let subscribe = function(f){
    // 接收了一个回调函数
    // react-redux给的
    // 这个回调函数 其实是 触发试图更新的一个操作
    // 什么时候让这个回调函数执行？？？
    // 我们redux 需要再数据更新之后再让这些回调函数执行
    listeners.push(f)
    console.log(arguments)
    return function () {
      // 这个回调函数会把当前事件 从是事件池中移除
      listeners = listeners.filter(item=>item!==f)
    }
  }
  dispatch({})//初始化state

  if(typeof fn === 'function'){
    return fn(createStore)(reducer)
  }

  return {
    getState,dispatch,subscribe
  }
}

export const combineReducers = function(obj){
  return function(state={},action){
    /* state {
      countReducer:{count:100},
      colorReducer:{color:'red}
    } */
    /* 
      obj {
        countReducer:count函数,
        colorReducer:color函数
      }
    */
    for(let reducer in obj){
      //obj[reducer] 对应的是  count函数 或者 color函数
      state[reducer] = obj[reducer](state[reducer],action)
    }
    return state
  }
}

// 中间件其实都是在dispatch执行的时候 起作用的
// 原理其实就是 把用户调用的dispatch 变成中间件的某某个方法
// 这个方法就可以做中间件想做的事情， 做完之后 再去执行原生的dispatch
// export const applyMiddleware = function(middleware){
//   return function(createStore){
//       return function(reducer){
//         let store = createStore(reducer);
//         let middle = middleware(store);
//         let midDispatch = middle(store.dispatch)
//         return {
//           ...store,
//           dispatch:midDispatch
//         }
//       }
//   }
// }

export const compose = (...fns)=> (...arg) =>{
  let first = fns.shift();
  return fns.reduce((prev,next)=>{
    return next(prev)
  },first(...arg))
}

export const applyMiddleware = (...middlewares) =>createStore => reducer =>{
  // /middlewares 存储的是所有的中间件  
  let store = createStore(reducer);
  // let middle = middleware(store);
  let middles = middlewares.map(item=>item(store))
  // let midDispatch = middle(store.dispatch)
  // let midDispatchs = middles.map(item=>item(store.dispatch))
  let midDispatch = compose(...middles)(store.dispatch)
  return {
    ...store,
    dispatch:midDispatch
  }
}


